package leetcode.code0273;

import leetcode.IDebug;
import leetcode.helper.HelpDebug;

public class Solution273 implements IDebug {

	private final String[] num119 = new String[] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
			"Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen",
			"Eighteen", "Nineteen" };
	private final String[] num2090 = new String[] { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
			"Eighty", "Ninety" };

	private final int billion = 1_000_000_000;
	private final int million = 1_000_000;
	private final int thousand = 1_000;
	private final int hundred = 100;

	private final int[] partsNum = new int[] { billion, million, thousand, hundred };
	private final String[] partsStr = new String[] { "Billion", "Million", "Thousand", "Hundred" };
	private final char blank = ' ';

	public String numberToWords(int num) {
		if (num == 0)
			return "Zero";
		StringBuffer ans = new StringBuffer();
		for (int i = 0; i < 3; i++) {
			num = this.part(num, i, ans);
		}
		ans.append(hundred(num));
		return ans.toString();
	}

	public int part(int num, int partIndex, StringBuffer ans) {
		int part = this.partsNum[partIndex];
		if (num >= part) {
			ans.append(this.hundred(num / part)).append(this.blank).append(this.partsStr[partIndex]);
			num = num % part;
			if (num != 0)
				ans.append(this.blank);
		}
		return num;
	}

	public String hundred(int num) {
		StringBuffer ans = new StringBuffer();
		if (num >= hundred) {
			int hnum = num / hundred;
			ans.append(num119[hnum]).append(this.blank).append(this.partsStr[3]);
			num = num % hundred;
			if (num != 0)
				ans.append(this.blank);
		}
		if (num > 19) {
			int hnum = num / 10;
			ans.append(num2090[hnum]);
			num = num % 10;
			if (num != 0) {
				ans.append(this.blank);
			}
		}
		if (num != 0)
			ans.append(num119[num]);
		return ans.toString();
	}

	@Override
	public void debug1() {
		int num = 123;
		String e = "One Hundred Twenty Three";
		String r = this.numberToWords(num);
		HelpDebug.compare(e, r);
	}

	@Override
	public void debug2() {
		int num = 12345;
		String e = "Twelve Thousand Three Hundred Forty Five";
		String r = this.numberToWords(num);
		HelpDebug.compare(e, r);
	}

	@Override
	public void debug3() {
		int num = 1234567;
		String e = "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven";
		String r = this.numberToWords(num);
		HelpDebug.compare(e, r);
	}

	@Override
	public void debug4() {
		int num = 1_234_567_891;
		String e = "One Billion Two Hundred Thirty Four Million Five Hundred Sixty Seven Thousand Eight Hundred Ninety One";
		String r = this.numberToWords(num);
		HelpDebug.compare(e, r);
	}

	public void debug5() {
		int num = 1_000;
		String e = "One Thousand";
		String r = this.numberToWords(num);
		HelpDebug.compare(e, r);
	}

	public static void main(String[] args) {
		Solution273 so = new Solution273();
		so.debug1();
		so.debug2();
		so.debug3();
		so.debug4();
		so.debug5();
		String ans = so.numberToWords(100);
		System.out.println(ans);
	}

}
